<template>
  <uni-drawer
    v-show="modelValue"
    ref="gdDrawerRef"
    :mode="mode"
    :mask-click="closeOnClickModal"
    :mask="modal"
    :width="drawerWidth"
    @change="onChange"
    class="gd-drawer-container"
  >
    <view class="header-container">
      <view class="title" v-if="!hasTitleSlot">{{ title }}</view>
      <view class="title">
        <slot name="title"></slot>
      </view>
      <view>
        <view style="display: flex; align-items: center">
          <slot name="header-right"></slot>
          <GdIcon
            v-if="isShowDrawerPin"
            :icon-name="`fluent:pin-${isDrawerPinned ? 'off-' : ''}20-filled`"
            style="cursor: pointer"
            @click="toggleDrawerPinned"
          ></GdIcon>
          <GdIcon
            icon-name="close"
            @click="onClose"
            class="header-icon"
          ></GdIcon>
        </view>
      </view>
    </view>
    <view class="content">
      <slot></slot>
    </view>
  </uni-drawer>
</template>
<script setup>
import { ref, shallowRef, watch, computed, onMounted, useSlots } from "vue";
import GdIcon from "@gd-accbuild-ui/gd-ui/gd-icon/gd-icon.vue";
const props = defineProps({
  isCache: {
    type: Boolean,
    default: false,
  },
  modelValue: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
  },
  direction: {
    type: String,
    default: "ltr",
  },
  modal: {
    type: Boolean,
    default: true,
  },
  width: {
    type: [Number, String],
    default: 220,
  },
  closeOnClickModal: {
    type: Boolean,
    default: true,
  },
  isDrawerPinned: {
    type: Boolean,
    default: false,
  },
  isShowDrawerPin: {
    type: Boolean,
    default: false,
  },
});

const drawerWidth = computed(() => {
  if (typeof props.width === "number") {
    return props.width; // + 'px';
  }
  // TODO:FIXME: 暂时只支持 两个数的加减 只支持单位 vw、px
  else if (typeof props.width === "string") {
    const valStrs = props.width.split(" ");
    const resultsVal = [];
    const res = uni.getSystemInfoSync();
    valStrs.forEach((str) => {
      if (str.endsWith("vw")) {
        resultsVal.push((+str.replace("vw", "") / 100) * res.windowWidth);
      } else if (str.endsWith("px")) {
        resultsVal.push(+str.replace("px", ""));
      } else {
        resultsVal.push(str);
      }
    });
    if (resultsVal[1] === "-") {
      return resultsVal[0] - resultsVal[2]; // + 'px';
    } else if (resultsVal[1] === "+") {
      return resultsVal[0] + resultsVal[2]; // + 'px';
    } else if (resultsVal.length === 1) {
      return resultsVal[0];
    } else {
      return 220;
    }
  } else {
    return 220;
  }
});
const mode = computed(() => {
  if (props.direction === "ltr") {
    return "left";
  } else if (props.direction === "rtl") {
    return "right";
  } else {
    return "left";
  }
});

const $slot = useSlots();
const hasTitleSlot = computed(() => {
  return $slot.hasOwnProperty("title");
});
const gdDrawerRef = ref(null);
const _emits = defineEmits(["update:modelValue", "update:isDrawerPinned"]);
const onClose = () => {
  _emits("update:modelValue", false);
};
watch(
  [() => props.width, drawerWidth],
  ([newVal1, newVal2], [oldVal1, oldVal2]) => {
    if (gdDrawerRef.value) {
      gdDrawerRef.value.drawerWidth = drawerWidth.value;
    }
  }
);
watch(
  () => props.modelValue,
  (newVal, oldVal) => {
    if (gdDrawerRef.value) {
      onDrawerStatusChange(props.modelValue);
    }
  }
);
const onChange = (val) => {
  if (!val) {
    onClose();
  }
};
const onDrawerStatusChange = (val) => {
  if (val) {
    gdDrawerRef.value.open();
  } else {
    if (!props.isCache) {
      gdDrawerRef.value.close();
    }
  }
};
onMounted(() => {
  onDrawerStatusChange(props.modelValue);
  gdDrawerRef.value.drawerWidth = props.width;
});

const toggleDrawerPinned = () => {
  _emits("update:isDrawerPinned", !props.isDrawerPinned);
};
const computedDrawerWidth = computed(() => {
  return props.isDrawerPinned ? drawerWidth.value : "100vw"
})
</script>
<style lang="scss" scoped>
.header-container {
  display: flex;
  align-items: center;
  height: 40px;
  justify-content: space-between;
  margin: 0 10rpx 0 20px;
  border-bottom: 1px solid #eee;
  z-index: 100;

  .title {
    color: #0f1726;
    font-size: 30rpx;
    font-weight: 700;
  }

  .header-icon {
    padding: 10rpx;
    cursor: pointer;
  }
}

.content {
  margin-top: 20rpx;
  width: 100%;
  height: calc(100% - 40px - 20rpx);
}
.gd-drawer-container {
  width: calc(v-bind(computedDrawerWidth) * 1px);
}
</style>
